﻿using Naruto.Redis;
using Naruto.TaskManagement.Application.HttpClientApps;
using Naruto.TaskManagement.Application.WeSocketService;
using Naruto.TaskManagement.Entitys.Const;
using Naruto.TaskManagement.Entitys.DTO;
using Naruto.TaskManagement.Entitys.Enums;
using Naruto.TaskManagement.Entitys.VM;
using Naruto.TaskManagement.Infrastructure;
using Naruto.TaskManagement.Infrastructure.Interface;
using Naruto.TaskManagement.IRepository;
using Naruto.WebSocket.Interface;
using System;
using System.Threading.Tasks;

namespace Naruto.TaskManagement.Application
{
    public class UserApps : IApp
    {
        private readonly IUserRepository userRepository;

        private readonly ITaskManageUnitOfWork unitOfWork;

        private readonly IEmail email;

        private readonly IRedisRepository redis;

        private readonly IOrganizationInviteRecordRepository inviteRecordRepository;

        private readonly IClientSend clientSend;

        private readonly AuthCenterHttpClient authCenterHttpClient;


        public UserApps(IUserRepository _userRepository, ITaskManageUnitOfWork _unitOfWork, IEmail _email, IRedisRepository _redis, IOrganizationInviteRecordRepository _inviteRecordRepository, IClientSend<TaskManagementSocketService> _clientSend, AuthCenterHttpClient _authCenterHttpClient)
        {
            userRepository = _userRepository;
            unitOfWork = _unitOfWork;
            email = _email;
            redis = _redis;
            inviteRecordRepository = _inviteRecordRepository;
            clientSend = _clientSend;
            authCenterHttpClient = _authCenterHttpClient;
        }
        /// <summary>
        /// 获取用户信息
        /// </summary>
        /// <returns></returns>
        public async Task<NarutoResult> GetUserInfoBase(string id)
        {
            if (id.IsNullEmpty())
            {
                return new NarutoFailResult("参数错误");
            }
            //获取用户信息
            var userInfo = await userRepository.GetUserInfoByUserId(id);
            if (userInfo == null)
            {
                return new NarutoFailResult("用户不存在");
            }
            return new NarutoSuccessResult("操作成功", userInfo);
        }
        /// <summary>
        /// 修改密码
        /// </summary>
        /// <param name="info"></param>
        /// <returns></returns>
        public async Task<NarutoResult> UpdatePassword(string userId, UpdatePasswordDTO info)
        {
            if (userId != info.userId)
            {
                return new NarutoFailResult("用户信息错误");
            }
            if (info.oldPswd.IsNullEmpty())
            {
                return new NarutoFailResult("请输入原始密码");
            }
            if (info.newPswd.IsNullEmpty())
            {
                return new NarutoFailResult("请输入新密码");
            }
            //获取当前用户的密码信息

            var userInfo = await userRepository.GetUserInfoById(userId);
            if (userInfo == null)
            {
                return new NarutoFailResult("无法获取用户的信息");
            }
            if (userInfo.Password != info.oldPswd.ToRsaDecrypt())
            {
                return new NarutoFailResult("旧密码输入错误");
            }
            info.newPswd = info.newPswd.ToRsaDecrypt();
            //调用接口  修改密码
            return await authCenterHttpClient.UpdatePassword(userId, info);
        }

        /// <summary>
        /// 注册
        /// </summary>
        /// <param name="info"></param>
        /// <returns></returns>
        public async Task<NarutoResult> Register(RegisterDTO info)
        {
            if (info.userName.IsNullEmpty())
            {
                return new NarutoFailResult("请输入用户名");
            }
            if (info.name.IsNullEmpty())
            {
                return new NarutoFailResult("请输入姓名");
            }
            if (info.password.IsNullEmpty())
            {
                return new NarutoFailResult("请输入密码");
            }
            if (info.email.IsNullEmpty())
            {
                return new NarutoFailResult("请输入邮箱地址");
            }
            //验证用户名是否存在
            if (await userRepository.ExistsUserName(info.userName))
            {
                return new NarutoFailResult("当前账号已经存在");
            }
            //验证邮箱是否存在
            if (await userRepository.ExistsEmail(info.email))
            {
                return new NarutoFailResult("当前邮箱已经存在");
            }
            info.password = info.password.ToRsaDecrypt();
            //调用接口
            return await authCenterHttpClient.Register(info);
        }

        /// <summary>
        /// 发送邮箱验证码
        /// </summary>
        /// <param name="info"></param>
        /// <returns></returns>
        public async Task<NarutoResult> SendEmailCode(SendEmailCodeDTO info)
        {
            if (info.email.IsNullEmpty())
            {
                return new NarutoFailResult("请输入邮箱地址");
            }
            //验证邮箱是否存在
            if (!await userRepository.ExistsEmail(info.email))
            {
                return new NarutoFailResult("当前邮箱不存在");
            }
            Random random = new Random();
            //验证码
            var code = random.Next(10000, 99999);
            //存储到缓存
            await redis.String.AddAsync(ConstObject.EmailCodeCacheKey + info.email, code, TimeSpan.FromMinutes(15));
            //模板
            var template = $"<div>【任务管理】你正在操作忘记密码，验证码为<span style ='text-decoration:underline;'>{code}</span>,有效期15分钟！</div>";
            //发送
            await email.SendEmailAsync(new System.Collections.Generic.List<string> { info.email }, "邮箱验证码", null, template);
            return new NarutoSuccessResult("操作成功");
        }


        /// <summary>
        /// 检查邮箱验证码
        /// </summary>
        /// <param name="info"></param>
        /// <returns></returns>
        public async Task<NarutoResult> CheckCode(CheckCodeDTO info)
        {
            if (info.email.IsNullEmpty())
            {
                return new NarutoFailResult("请输入邮箱地址");
            }
            if (info.code.IsNullEmpty())
            {
                return new NarutoFailResult("请输入验证码");
            }
            //检验验证码
            string code = await redis.String.GetAsync(ConstObject.EmailCodeCacheKey + info.email);
            if (code.IsNullEmpty())
            {
                return new NarutoFailResult("输入的验证码已过期");
            }
            if (code != info.code)
            {
                return new NarutoFailResult("输入的验证码错误");
            }
            return new NarutoSuccessResult("操作成功");
        }

        /// <summary>
        /// 根据邮箱重置密码
        /// </summary>
        /// <param name="info"></param>
        /// <returns></returns>
        public async Task<NarutoResult> ResetPswdByEmail(ResetPswdByEmailDTO info)
        {
            if (info.pswd.IsNullEmpty())
            {
                return new NarutoFailResult("请输入密码");
            }
            if (info.email.IsNullEmpty())
            {
                return new NarutoFailResult("请输入邮箱地址");
            }
            //验证邮箱是否存在
            if (!await userRepository.ExistsEmail(info.email))
            {
                return new NarutoFailResult("当前邮箱不存在");
            }
            info.pswd = info.pswd.ToRsaDecrypt();
            //调用接口
            return await authCenterHttpClient.ResetPswdByEmail(info);
        }

        public async Task<NarutoResult> GetOriginationUser(GetOriginationUserDTO info)
        {
            if (info.oid.IsNullEmpty())
            {
                return new NarutoFailResult("组织信息错误");
            }

            var list = await userRepository.GetUserByOrganizationId(info.oid);
            return new NarutoSuccessResult("操作成功", list);
        }

        /// <summary>
        /// 邀请用户到我的组织来
        /// </summary>
        /// <param name="info"></param>
        /// <returns></returns>
        public async Task<NarutoResult> AppointUserToMyOrganization(AppointUserToMyOrganizationDTO info)
        {
            if (info.userName.IsNullEmpty())
            {
                return new NarutoFailResult("邀请人的用户名不能为空");
            }
            if (info.inviteesUserName.IsNullEmpty())
            {
                return new NarutoFailResult("被邀请人的用户名不能为空");
            }
            //查找被邀请人账号是否存在
            var userInfo = await userRepository.GetUserInfoByUserName(info.inviteesUserName);
            if (userInfo == null)
                return new NarutoFailResult("被邀请人的用户名不存在");
            //查找邀请人账号是否存在
            if (!await userRepository.ExistsUserName(info.userName))
                return new NarutoFailResult("邀请人的用户名不存在");

            //获取被邀请人对应的组织id
            var inviteesOid = await userRepository.GetUserOrganizationId(info.inviteesUserName);
            //获取邀请人的组织id
            var oid = await userRepository.GetUserOrganizationId(info.userName);
            if (oid == inviteesOid)
            {
                return new NarutoFailResult("当前已经是同一组织无法继续邀请");
            }
            //新增邀请的记录表
            var addInfo = new Entitys.Models.OrganizationInviteRecord
            {
                Id = SnowFlakeHelper.NewID(),
                CreateTime = DateTime.Now,
                Status = (int)OrganizationInviteRecordStatusEnum.Pending,
                InviteUserName = info.userName,
                InviteesUserName = info.inviteesUserName,
            };
            await inviteRecordRepository.Add(addInfo);
            //提交数据
            await unitOfWork.SaveChangeAsync();

            //发送一条记录通知 被邀请人
            await clientSend.Current.SendAsync(userInfo.Id.ToString(), "organizationInvite", new SendInviteNoticeDTO
            {
                id = addInfo.Id,
                inviteUserName = info.userName
            });
            return new NarutoSuccessResult("操作成功");
        }

        /// <summary>
        /// 接受邀请
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public async Task<NarutoResult> AcceptInvite(string id)
        {
            //获取数据
            var info = await inviteRecordRepository.GetById(id);
            if (info == null)
                return new NarutoFailResult("无效的参数");
            //获取当前用户名对应的组织id
            var oid = await userRepository.GetUserOrganizationId(info.InviteUserName);
            //更新被邀请人的组织id
            await userRepository.UpdateOrganizationIdByUserName(info.InviteesUserName, oid);
            //更新记录的状态
            await inviteRecordRepository.UpdateStatusById(id, OrganizationInviteRecordStatusEnum.Processed);

            await unitOfWork.SaveChangeAsync();
            return new NarutoSuccessResult("操作成功");
        }

        /// <summary>
        /// 获取组织的用户信息
        /// </summary>
        /// <param name="id">组织id</param>
        /// <returns></returns>
        public async Task<NarutoResult> GetOrganizationUser(string id)
        {
            //获取组织下的用户信息
            var list = await userRepository.GetOrganizationIdUser(id);
            return new NarutoSuccessResult("操作成功", list);
        }


        public async Task<NarutoResult> GetUserInfo(string id)
        {
            var userInfo = await userRepository.GetUserBaseInfoById(id);
            return new NarutoSuccessResult("操作成功", userInfo);
        }
    }
}
